package cm.tl.pms.common.exception;

import cm.tl.pms.common.entity.ErrorEnum;
import cm.tl.pms.common.entity.ResultMsg;
import cn.hutool.core.text.StrPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;

/**
 * @Auther: lwp
 * @Date: 2022/11/17 - 11 - 17 - 16:33
 * @Description
 * @version: 1.0
 */
@ControllerAdvice
@Slf4j
public class ExceptionHandle {

    /**
     * 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public ResultMsg BindExceptionHandler(BindException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(StrPool.COMMA));
        ResultMsg<Object> resultMsg = ResultMsg.failResult(ErrorEnum.PARAM_ERROR);
        getMessage(message, resultMsg);
        return resultMsg;
    }


    /**
     * 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
     *
     * @param e
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public ResultMsg ConstraintViolationExceptionHandler(ConstraintViolationException e) {
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(StrPool.COMMA));
        ResultMsg<Object> resultMsg = ResultMsg.failResult(ErrorEnum.PARAM_ERROR);
        getMessage(message, resultMsg);

        return resultMsg;
    }

    /**
     * 处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultMsg MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(StrPool.COMMA));
        ResultMsg<Object> resultMsg = ResultMsg.failResult(ErrorEnum.PARAM_ERROR);
        getMessage(message, resultMsg);
        return resultMsg;
    }


    /**
     * 组装错误异常
     *
     * @param message
     * @param resultMsg
     */
    private void getMessage(String message, ResultMsg<Object> resultMsg) {
        String[] split = message.split(StrPool.COMMA);
        // 显示一个参数错误
        resultMsg.setResultMsg(split[0]);
/*        // 显示多个参数错误
        resultMsg.setResultMsg(message);*/
    }

    @ExceptionHandler(value = ApiBusinessException.class)
    @ResponseBody
    public ResultMsg handlerException(ApiBusinessException be) {
        log.error(be.getApiCodeMsg().getCode() + ": " + be.getApiCodeMsg().getMessage());
        return ResultMsg.failResult(be.getApiCodeMsg().getMessage());
    }

}
